﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Common;

public class StateEngine : Singleton<StateEngine> {
    static readonly int MAX_STACK_SIZE = 10;
    static gxGameState[] gameStateStack = new gxGameState[MAX_STACK_SIZE];//状态栈
    static int curStackIndex;
    static QuickList<gxGameState> delayReleaseState = new QuickList<gxGameState>();//需要清理的状态

    public override void Initialize()
    {
        curStackIndex = -1;//指向栈顶
    }
    public override void Uninitialize()
    {
        ClearStack();
    }

    public void ClearStack()
    {
        while (curStackIndex >= 0)
        {
            gameStateStack[curStackIndex].Pause();
            gameStateStack[curStackIndex].Release();
            gameStateStack[curStackIndex] = null;
            curStackIndex--;
        }

        while (delayReleaseState.Count > 0)
        {
            gxGameState gs = delayReleaseState.Pop();
            gs.Pause();
            gs.Release();
        }

    }

    public void ChangeState(gxGameState curState,ChangeStateType changeType)
    {
        if (curState == null)
        {
            Debug.Log("Change state error: the state you want to change is null!");
            return;
        }

        if (changeType == ChangeStateType.noDestroy)
        {
            if (curStackIndex >= MAX_STACK_SIZE - 1)
            {
                Debug.Log("State Stack is full,you can't change state with not destroy everything!");
                return;
            }
            if (curState.Init() == 0)
            {
                Debug.Log("State init error!");
            }
            else
            {
                curStackIndex++;
                gameStateStack[curStackIndex] = curState;
                curState.Resume();
            }
        }
        else if (changeType == ChangeStateType.destroyLast)
        {
            if (curState.Init() == 0)
            {
                 Debug.Log("State init error!");
            }
            else
            {
                if (curStackIndex == -1)
                {
                    curStackIndex = 0;
                    gameStateStack[curStackIndex] = curState;
                    curState.Resume();
                }
                else
                {
                    gxGameState popedgs = gameStateStack[curStackIndex];
                    gameStateStack[curStackIndex] = curState;
                    curState.Resume();
                    popedgs.Pause();
                    delayReleaseState.Add(popedgs);
                }
                
            }
        }
        else if (changeType == ChangeStateType.destroyEverything)
        {
            if (curState.Init() == 0)
            {
                Debug.Log("State init error!");
            }
            else
            {
                while (curStackIndex >= 0)
                {
                    gxGameState popedgs = gameStateStack[curStackIndex];
                    popedgs.Pause();
                    delayReleaseState.Add(popedgs);
                    curStackIndex--;
                }
                curStackIndex++;
                gameStateStack[curStackIndex] = curState;
                curState.Resume();
            }
        }
    }




	// Update is called once per frame
	public void Update (float deltaTime) {
        if (delayReleaseState.Count > 0)
        {
            gxGameState popedgs = delayReleaseState.Pop();
            popedgs.Release();
        }
        if (curStackIndex < 0)
        {
            return;
        }
        gameStateStack[curStackIndex].Update(deltaTime);
	}
}
